#include <iostream>
#include <vector>
#include <string>
#include <unistd.h>
#include <cstring>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

vector<char *> command;
char commandline[1024];
char *argv[5][32];
vector<int> indix;
void initline(char cline[])
{
    printf("[%s@%s-%s]$", getenv("USER"), getenv("HOSTNAME"), getenv("PWD"));
    fgets(cline, 1024, stdin);
    cline[strlen(cline) - 1] = 0;
}
int splitcommand(char commandline[], int size)
{
    int cnt = 1, end = 0;
    for (int i = 0; i < size - 1; i++)
    {
        if (commandline[i] == '|')
        {
            commandline[i] = '\0';
            command.push_back(commandline + end);
            end = i + 2;
            cnt++;
        }
    }
    command.push_back(commandline + end);
    return command.size();
}

void dispose(char *s, int j)
{

    int i = 0;
    argv[j][i++] = strtok(s, " ");
    while (argv[j][i++] = strtok(NULL, " "))
    {
        ;
    }
    indix.push_back(i - 1);
}

void splitstring(vector<char *> &command)
{

    for (int i = 0; i < command.size(); i++)
    {

        dispose(command[i], i);
    }
}
// bool buildcommand(char *_argv[5][32], int n)
bool buildcommand(char *_argv[], int n)
{

    if (indix[n - 1] == 2 && strcmp(_argv[0], "echo") == 0)
    {
        if (*_argv[1] == '$')
        {
            cout << getenv(_argv[1] + 1) << endl;
        }
        else if (*_argv[1] == '"')
        {
            printf("%s\n", _argv[1]);
        }
        return true;
    }
}

void normalexe(char *_argv[], int n)
{
    pid_t rpid = fork();
    if (rpid == 0)
    {
        execvp(_argv[0], _argv);
    }
    else
    {
        int status = 0;
        waitpid(rpid, &status, 0);
        cout << "exit code: " << ((status >> 8) & 0xFF) << " exit signs: " << (status & 0x7F) << endl;
    }
}

void bulidconnect(int n)
{
    int pipefd[2] = {0};
    int ret = pipe(pipefd);
    if (ret != 0)
        return;
    for (int i = 1; i <= n; i++)
    {
        pid_t rpid = fork();
        if (rpid == 0)
        {
            if (i == 1)
            {
                dup2(pipefd[1], 1);
                close(pipefd[0]);
                execvp(argv[i - 1][0], argv[i - 1]);
            }
            else
            {
                dup2(pipefd[0], 0);
                close(pipefd[1]);
                printf("%s\n", argv[i - 1][0]);
                execvp(argv[i - 1][0], argv[i - 1]);
            }
        }
    }

    close(pipefd[1]);
    close(pipefd[0]);
    printf("--------------\n");
    int status = 0;
    waitpid(-1, &status, 0);
    cout << "exit code: " << ((status >> 8) & 0xFF) << " exit signs: " << (status & 0x7F) << endl;
}
int main()
{
    while (1)
    {
        commandline[0] = 0;
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 32; j++)
            {
                argv[i][j] = 0;
            }
        }
        indix.clear();
        initline(commandline);
        command.clear();
        int cnt = splitcommand(commandline, sizeof(commandline));

        if (cnt == 1)
        {
            splitstring(command);
            bool ret = buildcommand(argv[0], 1);
            if (!ret)
                normalexe(argv[0], 1);
        }
        else
        {
            splitstring(command);
            bulidconnect(cnt);
            printf("8888888888888888888\n");
        }
    }
    return 0;
}